package com.alex.lib_zxingcode.zxing.encoding;

import android.graphics.Bitmap;
import android.graphics.Matrix;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;

import java.util.Hashtable;
/**
 * @author Ryan Tang
 *
 */
public final class EncodingHandler {
	private static final int BLACK = 0xff000000;
	
	/*
	 * 生成二维码图片的处理思路：
	 * 1.先按照指定的宽高要求创建一个空白Bitmap
	 * 2.将这个Bitmap对应的范围内平均切分成n个像素块
	 * 3.通过方式去计算当前的每个像素点上应该显示的数据
	 * 4.将所有的像素点上应该显示的数据计算完成后，拼接起来即可的到对应的二维码的图片
	 * */
	public static Bitmap createQRCode(String str,int widthAndHeight) throws WriterException {

		Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
       //设置稍后将文字转为数字解析时的字符编码
		hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
		/*
		 * 通过encode方法直接将文字转化成对应二维码图形块
		 * 方法中的参数：
		 * 1. 要解析的字符串
		 * 2. 要将字符串解析成何种编码，即二维码还是条形码
		 * 3，4. 生成的图形块的宽高
		 * 
		 * Matrix 矩阵
		 * */
		BitMatrix matrix = new MultiFormatWriter().encode(str,
				BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight);
		
		//获取图形块对应的宽高
		int width = matrix.getWidth();
		int height = matrix.getHeight();
		
		//根据图形块的宽高生成对应长度的像素数据的数组
		int[] pixels = new int[width * height];
		
		
		//根据宽高的值，进行双层的for循环，目的是在这个循环中给数组的每一个位置赋值
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				//根据get方法进行判断，判断当前x,y位置上是应该显示颜色还是不应该显示颜色
				if (matrix.get(x, y)) {
					//设置颜色
					pixels[y * width + x] = BLACK;
					
					//思考：假设将宽度一分为二，让左边显示红色，右边显示蓝色
//					if(x < (width /2)) {
//						pixels[y * width + x] = 0xffff0000;
//					} else {
//						pixels[y * width + x] = 0xff0000ff;
//					}
				} 
			}
		}
		
		Bitmap bitmap = Bitmap.createBitmap(width, height,
				Bitmap.Config.ARGB_8888);
		//将计算好的像素数组中的值设置到bitmap上进行显示
		bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
		return bitmap;
	}
	
	
	//自定义方法，用于生成中间带图片的二维码
	//注意：中心图形不能太大
	//参数三代表中心的图片
	public static Bitmap createQRCode(String str,int widthAndHeight,Bitmap centerBit) throws WriterException {
		//先将中心图片缩小，缩小成二维码图形块的1/8
		Matrix m = new Matrix();
		float sx = (widthAndHeight/8) / (float)centerBit.getWidth();
		float sy = (widthAndHeight/8) /  (float)centerBit.getHeight();
		m.setScale(sx, sy);
		Bitmap bitm = Bitmap.createBitmap(centerBit, 0, 0, centerBit.getWidth(), centerBit.getHeight(), m, true);
		
		Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();  
       //设置稍后将文字转为数字解析时的字符编码
		hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); 
		
		/*
		 * 通过encode方法直接将文字转化成对应二维码图形块
		 * 方法中的参数：
		 * 1. 要解析的字符串
		 * 2. 要将字符串解析成何种编码，即二维码还是条形码
		 * 3，4. 生成的图形块的宽高
		 * */
		BitMatrix matrix = new MultiFormatWriter().encode(str,
				BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight);
		//获取图形块对应的宽高
		int width = matrix.getWidth();
		int height = matrix.getHeight();
		//根据图形块的宽高生成对应长度的像素数据的数组
		int[] pixels = new int[width * height];
		
		int w = width / 2;
		int h = height / 2;
		int bw = bitm.getWidth() /2;
		int bh = bitm.getHeight() /2;
		//根据宽高的值，进行双层的for循环，目的是在这个循环中给数组的每一个位置赋值
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				//根据get方法进行判断，判断当前x,y位置上是应该显示颜色还是不应该显示颜色
				if (x > (w - bw) && x < (w+bw) 
						&& y > (h-bh) && y < (h+bh)){
					//判断当前像素点的位置是否应该显示图片
					//应该显示图片，那么就让该点的值为图片的值
					pixels[y * width + x] =  bitm.getPixel(x - (w-bw), y-(h-bh));
				} else {
					if (matrix.get(x, y)) {
						pixels[y * width + x] = BLACK;
					} 
				}
			}
		}
		
		Bitmap bitmap = Bitmap.createBitmap(width, height,
				Bitmap.Config.ARGB_8888);
		//将计算好的像素数组中的值设置到bitmap上进行显示
		bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
		return bitmap;
	}
	
	
	//用于生成条形码的方法
//	public static Bitmap getTiaoXingCode (String str, int widthss,int heightss) throws WriterException {
//		
//		Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();  
//	       //设置稍后将文字转为数字解析时的字符编码
//			hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); 
//			
//			/*
//			 * 通过encode方法直接将文字转化成对应二维码图形块
//			 * 方法中的参数：
//			 * 1. 要解析的字符串
//			 * 2. 要将字符串解析成何种编码，即二维码还是条形码
//			 * 3，4. 生成的图形块的宽高
//			 * */
//			
////			int codeWidth = 30 + // start guard
////					(80 * 6) + // left bars
////					5 + // middle guard
////					(40 * 6) + // right bars
////					30; // end guard
////
////			widthss = Math.max(codeWidth, widthss);
//
//			
//			BitMatrix matrix = new MultiFormatWriter().encode(str,
//					BarcodeFormat.EAN_13, widthss, heightss);
//			//获取图形块对应的宽高
//			int width = matrix.getWidth();
//			int height = matrix.getHeight();
//			//根据图形块的宽高生成对应长度的像素数据的数组
//			int[] pixels = new int[width * height];
//			
//			//根据宽高的值，进行双层的for循环，目的是在这个循环中给数组的每一个位置赋值
//			for (int y = 0; y < height; y++) {
//				for (int x = 0; x < width; x++) {
//					//根据get方法进行判断，判断当前x,y位置上是应该显示颜色还是不应该显示颜色
//					if (matrix.get(x, y)) {
//						pixels[y * width + x] = BLACK;
//						
//						//思考：假设将宽度一分为二，让左边显示红色，右边显示蓝色
////						if(x < (width /2)) {
////							pixels[y * width + x] = 0xffff0000;
////						} else {
////							pixels[y * width + x] = 0xff0000ff;
////						}
//					} 
//				}
//			}
//			
//			Bitmap bitmap = Bitmap.createBitmap(width, height,
//					Bitmap.Config.ARGB_8888);
//			//将计算好的像素数组中的值设置到bitmap上进行显示
//			bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
//			return bitmap;
//	}
}
